import styles from "./BinarySearchTree.less";
import { useEffect, useState, useRef } from "react";
import { BST } from "data-structure-typed";
import { InputNumber, Button, Input } from "antd";
import * as echarts from "echarts";
import { generateSchoolData, SchoolConfig } from "./functions/generateTreeData";

type BSTItem = {
    name: string;
    value: number;
};

export default () => {
    const [grades, setGrades] = useState<number>(5);
    const [minClasses, setMinClasses] = useState<number>(3);
    const [maxClasses, setMaxClasses] = useState<number>(5);
    const [minStudents, setMinStudents] = useState<number>(5);
    const [maxStudents, setMaxStudents] = useState<number>(8);
    const [minValue, setMinValue] = useState<number>(40);
    const [maxValue, setMaxValue] = useState<number>(95);

    const [mockData, setMockData] = useState<any>();

    const [bst, setBst] = useState<BST>();

    const [searchName, setSearchName] = useState<string>('');
    const [searchResult, setSearchResult] = useState<string>('');

    const chart = useRef<any>(null);

    useEffect(() => {
        const chartDom = document.getElementById("BST");
        const c = echarts.init(chartDom);
        chart.current = c;

        const resizeHandler = () => {
            chart.current?.resize();
        };
        window.addEventListener('resize', resizeHandler);
        return () => {
            window.removeEventListener('resize', resizeHandler);
        }
    }, []);

    useEffect(() => {
        if (mockData) {
            chart.current?.setOption(buildOption(mockData));
            const array = treeToArray(mockData?.children);
            const tree = new BST<string, number>();
            tree.addMany(array);
            setBst(tree);
        }
    }, [mockData, searchResult]);

    const buildOption = (data: any[]) => {
        return {
            tooltip: {
                trigger: "item",
                triggerOn: "mousemove",
            },
            grid: {
                left: '0%',
                right: '0%',
                top: '25%',
                bottom: '0%',
            },
            series: [
                {
                    type: "tree",
                    data: [data],
                    left: "2%",
                    right: "2%",
                    top: "8%",
                    bottom: "20%",
                    symbol: "emptyCircle",
                    orient: "vertical",
                    expandAndCollapse: true,
                    initialTreeDepth: 5,
                    emphasis: {
                        focus: 'ancestor'
                    },
                    label: {
                        position: "top",
                        rotate: -90,
                        verticalAlign: "middle",
                        align: "right",
                        fontSize: 10,

                        formatter: function(params: any) {
                            if (params.name === searchResult) {
                                return '{a|' + params.name + '}';
                            } else {
                                return params.name;
                            }
                        },
                        rich: {
                            a: {
                                fontSize: 12,
                                color: '#f00',
                                fontWeight: 'bold',
                            }
                        }
                    },
                    leaves: {
                        label: {
                            position: "bottom",
                            rotate: -90,
                            verticalAlign: "middle",
                            align: "left",
                        },
                    },
                    animationDurationUpdate: 750,
                },
            ],
        };
    };

    const treeToArray = (tree: any[]): [string, number][] => {
        const result: [string, number][] = [];

        function dfs(node: any) {
            // 如果节点没有子节点，则认为是叶子节点
            if (!node.children?.length) {
                result.push([node.name, node.value]);
            } else {
                // 如果节点有子节点，则递归遍历子节点
                node.children.forEach((child: any) => dfs(child));
            }
        }

        // 遍历树的每个根节点
        tree.forEach((rootNode) => dfs(rootNode));

        return result;
    };

    const generateMockData = () => {
        const schoolConfig: SchoolConfig = {
            grades,
            minClassesPerGrade: minClasses,
            maxClassesPerGrade: maxClasses,
            minStudentsPerClass: minStudents,
            maxStudentsPerClass: maxStudents,
            minStudentValue: minValue,
            maxStudentValue: maxValue,
        };
        const schoolData = generateSchoolData(schoolConfig);
        setMockData(schoolData);
    };

    const search = () => {
        const r = bst?.get(searchName);
        setSearchResult(r);
    }

    return (
        <div className={styles.content}>
            <div className={styles.row}>
                <InputNumber
                    addonBefore="年级数"
                    value={grades}
                    onChange={(value: number | null) => setGrades(value || 0)}
                />
                <InputNumber
                    addonBefore="班级数"
                    value={minClasses}
                    onChange={(value: number | null) =>
                        setMinClasses(value || 0)
                    }
                />
                -
                <InputNumber
                    value={maxClasses}
                    onChange={(value: number | null) =>
                        setMaxClasses(value || 0)
                    }
                />
                <InputNumber
                    addonBefore="学生数"
                    value={minStudents}
                    onChange={(value: number | null) =>
                        setMinStudents(value || 0)
                    }
                />
                -
                <InputNumber
                    value={maxStudents}
                    onChange={(value: number | null) =>
                        setMaxStudents(value || 0)
                    }
                />
                <InputNumber
                    addonBefore="分数"
                    value={minValue}
                    onChange={(value: number | null) => setMinValue(value || 0)}
                />
                -
                <InputNumber
                    defaultValue={6}
                    value={maxValue}
                    onChange={(value: number | null) => setMaxValue(value || 0)}
                />
                <Button className={styles.generate} onClick={generateMockData}>
                    生成数据
                </Button>

                <div className={styles.searchLayout}>
                    <Input
                        placeholder="姓名"
                        value={searchName}
                        style={{ width: 100 }}
                        onChange={(e: { target: { value: string } }) => setSearchName(e.target.value)}
                    />
                    <Button className={styles.generate} onClick={search}>
                        查询
                    </Button>
                    <span>{searchResult ? `${searchResult}分` : ''}</span>
                </div>
            </div>

            <div id="BST" className={styles.chart} />
        </div>
    );
};
